package fit.deni.pages;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.corelib.components.BeanEditForm;
import org.apache.tapestry5.ioc.annotations.Inject;

import fit.deni.beans.Clan;
import fit.deni.beans.DVD;
import fit.deni.beans.Iznajmljivanje;
import fit.deni.beans.Klub;
import fit.deni.beans.Zaposleni;
import fit.deni.hibernate.interfaces.ClanService;
import fit.deni.hibernate.interfaces.DVDService;
import fit.deni.hibernate.interfaces.IznajmljivanjeService;
import fit.deni.hibernate.interfaces.KlubService;
import fit.deni.hibernate.interfaces.LogService;
import fit.deni.utils.Utils;

public class Rents {
	
	@Property
	private Collection<Iznajmljivanje> iznajmljivanja;
	@Property
	private Iznajmljivanje singleIznajmljivanje;
	@Persist(PersistenceConstants.FLASH)
	@Property
	private Iznajmljivanje novoIznajmljivanje;
	
	@Property
	private Clan customer;
	@Property
	private List<DVD> dvds;
	@Property
	private Klub selectedClub;
	
	@Property
	@SessionState
	private Zaposleni korisnik;
	private boolean korisnikExists;

	@Inject
	private IznajmljivanjeService iznajmljivanjeService;
	@Inject
	private ClanService clanService;
	@Inject
	private DVDService dvdService;
	@Inject
	private KlubService klubService;
	@Inject
	private LogService logService;
	
	@InjectPage
	private Rent rent;
	
	@Component
	private BeanEditForm forma; 
	
	@Property
	private ValueEncoder<DVD> encoder = new ValueEncoder<DVD>() {
		public String toClient(DVD value) {
			return value.getPrevod();
		}
		public DVD toValue(String clientValue) {
			return dvdService.getDVDbyTitle(clientValue);
		}
	};
	
	@Property
	private ValueEncoder<Klub> encoderClub = new ValueEncoder<Klub>() {
		public String toClient(Klub value) {
			return value.getIme();
		}
		public Klub toValue(String clientValue) {
			return klubService.getClubByName(clientValue);
		}
	};
	
	public List<Clan> getAllCustomers() {
		return new LinkedList<Clan>(clanService.getAll());
	}
	public List<DVD> getAllDVDs() {
		return new LinkedList<DVD>(dvdService.getAll());
	}
	public List<Klub> getAllClubs() {
		return new LinkedList<Klub>(klubService.getAll());
	}
	
	private double calculatePrice() {
		double profit = 0;
		for (DVD dvd : dvds) {
			profit += dvd.getCijena();
		}
		profit *= Utils.daysBetween(
				novoIznajmljivanje.getDatumIznajmljivanja(), 
				novoIznajmljivanje.getDatumVracanja());
		return profit;
		
	}

	private Object onActivate() {
		if(!korisnikExists) return Login.class;
		iznajmljivanja = iznajmljivanjeService.getAll();
		return null;
	}

	private Object onSuccess() {
		novoIznajmljivanje.setZarada(calculatePrice());
		novoIznajmljivanje.setClan(customer);
		novoIznajmljivanje.setKlub(selectedClub);
		novoIznajmljivanje.setDvds(dvds);
		for (DVD dvd : dvds) {
			dvd.setPutaIznajmljen(dvd.getPutaIznajmljen()+1);
			dvdService.addDVD(dvd);
		}
		iznajmljivanjeService.addRent(novoIznajmljivanje);
		logService.addLog(Utils.createPersonalisedLog(korisnik, " rented " + dvds.size() + " DVD-s"));
		novoIznajmljivanje = new Iznajmljivanje();
		return this;
	}
	
	private void onValidateFromForma(){
		if(customer==null || dvds.size() < 1) {
			forma.recordError("Unos klijenta je obavezan");
		}
		if(dvds.size() < 1) {
			forma.recordError("Morate odabrati makar jedan DVD");
		}
		int diff = Utils.daysBetween(novoIznajmljivanje.getDatumIznajmljivanja(), novoIznajmljivanje.getDatumVracanja());
		if (diff < 1) {
			forma.recordError("Datum vracanja mora da bude veci od datuma iznajmljivanja");
		}
	}

	public void onDelete(String id) {
		try {
			iznajmljivanjeService.deleteRent(iznajmljivanjeService.getRentById(Integer.parseInt(id)));
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Here you should handle delete errors");
		}
	}
	
	public Object onSelect(String id) {
		Iznajmljivanje i = iznajmljivanjeService.getRentById(Integer.parseInt(id));
		rent.setIzn(i);
		return rent;
	}

}
